package jmind.core.support;

import jmind.base.util.DataUtil;
import jmind.base.util.GlobalConstants;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 拼音工具
 * pinyin4j
 * @author weibo.xie
 * 2011-12-2
 */
public class PinYinUtil {

    private static final Logger log = LoggerFactory.getLogger(PinYinUtil.class);

    /**
     * 汉语拼音格式输出类, 输出设置, 大小写, 音标方式等
     */
    private static final HanyuPinyinOutputFormat FORMAT = new HanyuPinyinOutputFormat();

    static {
        FORMAT.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        FORMAT.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        FORMAT.setVCharType(HanyuPinyinVCharType.WITH_V);
    }

    /**
     * 获取拼音集合(多音字的各种排列)
     * @param src
     * @return Set<String>
    public static Set<String> getPinyinMulti(final String src) {
        final String[] pinyin = exchange(temp); // 组合爆炸
        return Sets.newHashSet(pinyin);
        return null;
    }
     */

    private static String[][] getPinyinRaw(final String src) {
        if (src != null && !src.trim().isEmpty()) {
            char[] chars = src.toCharArray();

            // 每个字符可以对应多个音
            final String[][] result = new String[src.length()][];
            for (int i = 0; i < chars.length; i++) {
                final char c = chars[i];
                // 转换拼音(是保留中文或a-z,A-Z)  
                if (isChineseCharacter(c)) { // 中文
                    try {
                        result[i] = PinyinHelper.toHanyuPinyinStringArray(chars[i], FORMAT);
                    } catch (BadHanyuPinyinOutputFormatCombination e) {
                        log.warn("bad hanyu pinyin output format combination", e);
                    }
                } else if (isLetters(c)) { // 英文字母
                    result[i] = new String[] { String.valueOf(chars[i]) };
                } else {
                    result[i] = new String[] { "" };
                }
            }
            return result;
        }
        return new String[][] {};
    }

    /**
     * 获取拼音
     * @param src
     * @return
     */
    public static String getPinyin(final String src) {
        return getPinyin(src, DataUtil.EMPTY);
    }

    public static String getPinyin(final String src, String sign) {
        final StringBuilder result = new StringBuilder();
        final String[][] pinyinRaw = getPinyinRaw(src);
        for (final String[] pinyin : pinyinRaw) {
            if (result.length() > 0)
                result.append(sign);
            result.append(pinyin[0]);
        }
        return result.toString();
    }

    /**
     * 递归
     * @param input [字符(索引)][多个读音]
     * @return
    private static String[] exchange(String[][] input) {
        final String[][] temp = doExchange(input);
        return temp[0];
    }
     */

    /**
     * 生成所有排列, 递归
     * @param input [字符(索引)][多个读音]
     * @return
    private static String[][] doExchange(String[][] input) {
        final int length = input.length;
        if (length >= 2) {
            final int length0 = input[0].length;
            final int length1 = input[1].length;
            final int newLength = length0 * length1;
            final String[] temp = new String[newLength];
            
            int Index = 0;
            for (int i = 0; i < length0; i++) {
                for (int j = 0; j < length1; j++) {
                    temp[Index] = input[0][i] + CHAR_DELIMETER + input[1][j];
                    Index++;
                }
            }
            final String[][] newArray = new String[length - 1][];
            for (int i = 2; i < length; i++) {
                newArray[i - 1] = input[i];
            }
            newArray[0] = temp;
            return doExchange(newArray);
        } else {
            return input;
        }
    }
     */

    /**
     * 是否汉字
     * @return
     */
    public static boolean isChineseCharacter(final char c) {
        return String.valueOf(c).matches(GlobalConstants.CHINESE_REGEX);
    }

    /**
     * 是否英文字母, a-z或A-Z
     * @return
     */
    private static boolean isLetters(final char c) {
        return (c >= 65 && c <= 90) || (c >= 97 && c <= 122);
    }

    /**
     * 字符串集合转换字符串(逗号分隔)
     * @param stringSet
     * @return
    private static String toString(final Set<String> stringSet) {
        final StringBuilder str = new StringBuilder();
        int i = 0;
        for (final String s : stringSet) {
            if (i == stringSet.size() - 1) {
                str.append(s);
            } else {
                str.append(s).append(WORD_DELIMETER);
            }
            i++;
        }
        return str.toString().toLowerCase();
    }
     */

    /** 
     * @param args 
     */
    public static void main(String[] args) {
        final String src = "长沙市,重庆重视发展IT行业，大多数外企，如，IBM等进驻山城";
        System.out.println(getPinyin(src));
        //        System.out.println(src.matches(""));
        //        System.out.println(getPinyin(src));

    }
}
